import {
    WebSocketEvent,
    WebSocketMessage,
    WebSocketOptions,
    WebSocketListener
  } from '@/api/websocket'

  class WebSocketService {
    private socket: WebSocket | null = null
    private listeners: Map<WebSocketEvent, Set<WebSocketListener>> = new Map()
    private reconnectAttempts: number = 0
    private options: Required<WebSocketOptions>
    private heartbeatTimer: number | null = null
  
    constructor(options: WebSocketOptions) {
      this.options = {
        maxReconnectAttempts: 5,
        reconnectInterval: 3000,
        heartbeatInterval: 30000,
        ...options
      }
  
      this.initialize()
    }
  
    private initialize(): void {
      this.socket = new WebSocket(this.options.url)
  
      this.socket.onopen = (event: Event) => {
        console.log('WebSocket connected')
        this.reconnectAttempts = 0
        this.startHeartbeat()
        this.emit('open', event)
      }
  
      this.socket.onmessage = (event: MessageEvent) => {
        try {
          const data: WebSocketMessage = JSON.parse(event.data)
          this.emit('message', data)
        } catch (error) {
          console.error('Error parsing WebSocket message:', error)
          this.emit('error', error)
        }
      }
  
      this.socket.onclose = (event: CloseEvent) => {
        console.log('WebSocket disconnected')
        this.stopHeartbeat()
        this.emit('close', event)
        this.handleReconnect()
      }
  
      this.socket.onerror = (event: Event) => {
        console.error('WebSocket error:', event)
        this.emit('error', event)
      }
    }
  
    public send<T>(data: WebSocketMessage<T>): void {
      if (this.socket?.readyState === WebSocket.OPEN) {
        const message: WebSocketMessage<T> = {
          ...data,
          timestamp: Date.now()
        }
        this.socket.send(JSON.stringify(message))
      } else {
        console.error('WebSocket is not connected')
        throw new Error('WebSocket is not connected')
      }
    }
  
    public on<T>(event: WebSocketEvent, listener: WebSocketListener<T>): void {
      if (!this.listeners.has(event)) {
        this.listeners.set(event, new Set())
      }
      this.listeners.get(event)?.add(listener as WebSocketListener)
    }
  
    public off<T>(event: WebSocketEvent, listener: WebSocketListener<T>): void {
      this.listeners.get(event)?.delete(listener as WebSocketListener)
    }
  
    public close(): void {
      if (this.socket) {
        this.socket.close()
        this.stopHeartbeat()
        this.listeners.clear()
      }
    }
  
    private emit<T>(event: WebSocketEvent, data?: T): void {
      this.listeners.get(event)?.forEach(listener => listener(data))
    }
  
    private startHeartbeat(): void {
      this.stopHeartbeat()
      this.heartbeatTimer = window.setInterval(() => {
        this.send({ type: 'heartbeat' })
      }, this.options.heartbeatInterval)
    }
  
    private stopHeartbeat(): void {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer)
        this.heartbeatTimer = null
      }
    }
  
    private handleReconnect(): void {
      if (this.reconnectAttempts < this.options.maxReconnectAttempts) {
        this.reconnectAttempts++
        console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`)
        setTimeout(() => this.initialize(), this.options.reconnectInterval)
      } else {
        console.log('Max reconnection attempts reached')
      }
    }
  }
  
  // 创建单例实例
  const webSocketService = new WebSocketService({
    url: "ws://localhost:8080/ws"
  })
  
  export default webSocketService